package com.crowntit.trigger.http;

import com.alibaba.fastjson.JSON;
import com.crowntit.api.IMarketTradeService;
import com.crowntit.api.dto.MarketTradeLockOrderRequestDTO;
import com.crowntit.api.dto.MarketTradeLockOrderResponseDTO;
import com.crowntit.api.dto.MarketTradeSettlementOrderRequestDTO;
import com.crowntit.api.dto.MarketTradeSettlementOrderResponseDTO;
import com.crowntit.api.response.Response;
import com.crowntit.domain.activity.model.entity.MarketProductEntity;
import com.crowntit.domain.activity.model.entity.TrialBalanceEntity;
import com.crowntit.domain.activity.model.valobj.GroupBuyActivityDiscountVO;
import com.crowntit.domain.activity.service.IIndexGroupBuyMarketService;
import com.crowntit.domain.trade.model.entity.*;
import com.crowntit.domain.trade.service.ITradeLockOrderService;
import com.crowntit.domain.trade.service.ITradeOrderSettlementService;
import com.crowntit.types.enums.NotifyTaskTypeEnumVO;
import com.crowntit.types.enums.ResponseCode;
import com.crowntit.types.exception.AppException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

@Slf4j
@RestController
@CrossOrigin("*")
@RequestMapping("/api/v1/gbm/trade/")
public class MarketTradeController implements IMarketTradeService {

    @Resource
    private ITradeLockOrderService tradeOrderService;
    @Resource
    private IIndexGroupBuyMarketService trialService;
    @Resource
    private ITradeOrderSettlementService tradeOrderSettlementService;

    /**
     * 拼团营销锁单
     */
    @RequestMapping(value = "lock_market_pay_order", method = RequestMethod.POST)
    @Override
    public Response<MarketTradeLockOrderResponseDTO> lockMarketTradeOrder(@RequestBody MarketTradeLockOrderRequestDTO requestDTO) {
        try {
            // 1. 参数校验
            Long activityId = requestDTO.getActivityId();
            String userId = requestDTO.getUserId();
            String source = requestDTO.getSource();
            String channel = requestDTO.getChannel();
            String goodsId = requestDTO.getGoodsId();
            String outTradeNo = requestDTO.getOutTradeNo();
            String notifyUrl = requestDTO.getNotifyUrl();

            log.info("营销交易锁单:{} LockMarketPayOrderRequestDTO:{}", userId, JSON.toJSONString(requestDTO));
            if (activityId == null || StringUtils.isBlank(userId) || StringUtils.isBlank(source) || StringUtils.isBlank(channel) || StringUtils.isBlank(goodsId) || StringUtils.isBlank(outTradeNo) || StringUtils.isBlank(notifyUrl)) {
                Response.<MarketTradeLockOrderResponseDTO>builder()
                        .code(ResponseCode.ILLEGAL_PARAMETER.getCode())
                        .info(ResponseCode.ILLEGAL_PARAMETER.getInfo())
                        .data(null)
                        .build();
            }

            // 2. 切量&降级拦截（暂不做）

            // 3. 拼团查询
            LockPayOrderEntity payOrder = tradeOrderService.queryMarketTradeOrderListByOutTradeNo(source, channel, userId, outTradeNo);
            if ( payOrder != null) {
                log.info("交易锁单记录(存在):{} marketPayOrderEntity:{}", userId, JSON.toJSONString( payOrder));

                MarketTradeLockOrderResponseDTO responseDTO = MarketTradeLockOrderResponseDTO.builder()
                        .outTradeNo( payOrder.getOutTradeNo())
                        .deductionPrice( payOrder.getDeductionPrice())
                        .payPrice(payOrder.getPayPrice())
                        .tradeOrderStatusEnumVO( payOrder.getStatus().getCode())
                        .validStartTime(payOrder.getValidStartTime())
                        .validEndTime(payOrder.getValidEndTime())
                        .build();

                return Response.<MarketTradeLockOrderResponseDTO>builder()
                        .code(ResponseCode.SUCCESS.getCode())
                        .info(ResponseCode.SUCCESS.getInfo())
                        .data(responseDTO)
                        .build();
            }

            // 4. 拼团目标是否达成
            String teamId = requestDTO.getTeamId();
            if (StringUtils.isNotBlank(teamId)) {
                boolean isGroupBuyComplete = tradeOrderService.isGroupBuyComplete(teamId);
                if (isGroupBuyComplete) {
                    log.info("交易锁单拦截-拼单目标已达成:{} {}", userId, teamId);
                    Response.<MarketTradeLockOrderResponseDTO>builder()
                            .code(ResponseCode.E0005.getCode())
                            .info(ResponseCode.E0005.getInfo())
                            .build();
                }
            }

            // 5. 优惠试算
            TrialBalanceEntity trialBalanceEntity = trialService.indexMarketTrial(MarketProductEntity.builder()
                    .activityId(activityId)
                    .channel(channel)
                    .source(source)
                    .userId(userId)
                    .goodsId(goodsId)
                    .build());

            // 人群限定
            if (!trialBalanceEntity.getIsVisible() || !trialBalanceEntity.getIsEnable()){
                return Response.<MarketTradeLockOrderResponseDTO>builder()
                        .code(ResponseCode.E0006.getCode())
                        .info(ResponseCode.E0006.getInfo())
                        .build();
            }

            // 6. 插入orderlist&更新order
            GroupBuyActivityDiscountVO groupBuyActivityDiscountVO = trialBalanceEntity.getGroupBuyActivityDiscountVO();
            UserEntity userEntity = UserEntity.builder()
                    .userId(userId)
                    .build();
            LockOrderActivityEntity activityEntity = LockOrderActivityEntity.builder()
                    .activityId(activityId)
                    .activityName(groupBuyActivityDiscountVO.getActivityName())
                    .startTime(trialBalanceEntity.getStartTime())
                    .endTime(trialBalanceEntity.getEndTime())
                    .teamId(teamId)
                    .targetCount(trialBalanceEntity.getTargetCount())
                    .validTime(groupBuyActivityDiscountVO.getValidTime())
                    .build();
            LockOrderDiscountEntity discountEntity = LockOrderDiscountEntity.builder()
                    .channel(channel)
                    .source(source)
                    .goodsId(goodsId)
                    .deductionPrice(trialBalanceEntity.getDeductionPrice())
                    .originalPrice(trialBalanceEntity.getOriginalPrice())
                    .payPrice(trialBalanceEntity.getPayPrice())
                    .goodsName(trialBalanceEntity.getGoodsName())
                    .outTradeNo(outTradeNo)
                    .build();
            NotifyEntity notifyEntity;
            if (StringUtils.isBlank(notifyUrl)){
                notifyEntity = NotifyEntity.builder()
                        .notifyType(NotifyTaskTypeEnumVO.MQ.getCode())
                        .build();
            } else {
                notifyEntity = NotifyEntity.builder()
                        .notifyType(NotifyTaskTypeEnumVO.HTTP.getCode())
                        .notifyUrl(notifyUrl)
                        .build();
            }

            LockPayOrderEntity lockPayOrderEntity = tradeOrderService.lockMarketTradeOrder(userEntity, activityEntity, discountEntity, notifyEntity);

            // 7. 返回数据
            MarketTradeLockOrderResponseDTO responseDTO = MarketTradeLockOrderResponseDTO.builder()
                    .outTradeNo(lockPayOrderEntity.getOutTradeNo())
                    .deductionPrice(lockPayOrderEntity.getDeductionPrice())
                    .payPrice(lockPayOrderEntity.getPayPrice())
                    .tradeOrderStatusEnumVO(lockPayOrderEntity.getStatus().getCode())
                    .validStartTime(lockPayOrderEntity.getValidStartTime())
                    .validEndTime(lockPayOrderEntity.getValidEndTime())
                    .build();
            log.info("锁单接口出参: {}", JSON.toJSONString(responseDTO));

            return Response.<MarketTradeLockOrderResponseDTO>builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .info(ResponseCode.SUCCESS.getInfo())
                    .data(responseDTO)
                    .build();

        } catch (AppException e) {
            log.error("营销交易锁单业务异常:{} LockMarketPayOrderRequestDTO:{}", requestDTO.getUserId(), JSON.toJSONString(requestDTO), e);
            return Response.<MarketTradeLockOrderResponseDTO>builder()
                    .code(e.getCode())
                    .info(e.getInfo())
                    .build();
        } catch (Exception e) {
            log.error("营销交易锁单服务失败:{} LockMarketPayOrderRequestDTO:{}", requestDTO.getUserId(), JSON.toJSONString(requestDTO), e);
            return Response.<MarketTradeLockOrderResponseDTO>builder()
                    .code(ResponseCode.UN_ERROR.getCode())
                    .info(ResponseCode.UN_ERROR.getInfo())
                    .build();
        }
    }

    /**
     * 拼团营销交易结算
     */
    @RequestMapping(value = "settlement_market_pay_order", method = RequestMethod.POST)
    @Override
    public Response<MarketTradeSettlementOrderResponseDTO> settlementMarketTradeOrder(@RequestBody MarketTradeSettlementOrderRequestDTO requestDTO) throws Exception {
        log.info("交易结算接口-入参：{} ", JSON.toJSONString(requestDTO));
        String source = requestDTO.getSource();
        String channel = requestDTO.getChannel();
        String outTradeNo = requestDTO.getOutTradeNo();
        String userId = requestDTO.getUserId();

        if (StringUtils.isBlank(source) || StringUtils.isBlank(channel) || StringUtils.isBlank(userId) || StringUtils.isBlank(outTradeNo)){
            return Response.<MarketTradeSettlementOrderResponseDTO>builder()
                    .code(ResponseCode.ILLEGAL_PARAMETER.getCode())
                    .info(ResponseCode.ILLEGAL_PARAMETER.getInfo())
                    .data(null)
                    .build();
        }

        TradeOrderSettlementEntity tradeOrderSettlementEntity = tradeOrderSettlementService.settlementMarketPayOrder(TradeOrderPaySuccessEntity.builder()
                .outTradeNo(outTradeNo)
                .userId(userId)
                .channel(channel)
                .source(source)
                .build());
        return Response.<MarketTradeSettlementOrderResponseDTO>builder()
                .code(ResponseCode.SUCCESS.getCode())
                .info(ResponseCode.SUCCESS.getInfo())
                .data(MarketTradeSettlementOrderResponseDTO.builder()
                        .userId(userId)
                        .teamId(tradeOrderSettlementEntity.getTeamId())
                        .activityId(tradeOrderSettlementEntity.getActivityId())
                        .outTradeNo(outTradeNo)
                        .orderStatus(tradeOrderSettlementEntity.getOrderStatus())
                        .groupBuyTeamStatus(tradeOrderSettlementEntity.getGroupBuyTeamStatus())
                        .build())
                .build();
    }
}
